Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20240116 ms extensions #18

Merged
merged 7 commits into from Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -33,5 +33,6 @@ uuid = { version = "^1.0.0", features = ["serde"] }
tracing = "^0.1.34"
hex = "0.4"


[dev-dependencies]
tracing-subscriber = "^0.3.11"
3 changes: 3 additions & 0 deletions src/compact.rs
Expand Up @@ -305,6 +305,9 @@ pub enum JweAlg {
/// RSA-OAEP
#[serde(rename = "RSA-OAEP")]
RSA_OAEP,
/// Direct
#[serde(rename = "dir")]
DIRECT,
}

#[derive(Debug, Serialize, Copy, Clone, Deserialize, PartialEq, Default)]
Expand Down
14 changes: 13 additions & 1 deletion src/crypto/a256gcm.rs
Expand Up @@ -19,6 +19,13 @@ pub struct JweA256GCMEncipher {
aes_key: [u8; KEY_LEN],
}

#[cfg(test)]
impl JweA256GCMEncipher {
pub(crate) fn assert_key(&self, key: &[u8]) -> bool {
self.aes_key == key
}
}

impl TryFrom<&[u8]> for JweA256GCMEncipher {
type Error = JwtError;

Expand All @@ -27,7 +34,7 @@ impl TryFrom<&[u8]> for JweA256GCMEncipher {
return Err(JwtError::InvalidKey);
}

let mut aes_key = [0; 32];
let mut aes_key = [0; KEY_LEN];
aes_key.copy_from_slice(r_aes_key);

Ok(JweA256GCMEncipher { aes_key })
Expand Down Expand Up @@ -67,6 +74,7 @@ impl JweEncipherInner for JweA256GCMEncipher {

let content_enc_key = outer.wrap_key(&self.aes_key)?;

// IV must always be random!
let mut iv = vec![0; IV_LEN];
rand_bytes(&mut iv).map_err(|ossl_err| {
debug!(?ossl_err);
Expand Down Expand Up @@ -94,6 +102,10 @@ impl JweEncipherInner for JweA256GCMEncipher {
}

impl JweA256GCMEncipher {
pub(crate) fn ms_oapxbc_key(&self) -> &[u8] {
&self.aes_key
}

pub fn key_len() -> usize {
KEY_LEN
}
Expand Down
3 changes: 1 addition & 2 deletions src/crypto/hs256.rs
Expand Up @@ -74,7 +74,6 @@ impl JwsHs256Signer {
}
}

#[cfg(test)]
impl TryFrom<&[u8]> for JwsHs256Signer {
type Error = JwtError;

Expand All @@ -86,7 +85,7 @@ impl TryFrom<&[u8]> for JwsHs256Signer {
let digest = hash::MessageDigest::sha256();

let kid = hash::hash(digest, buf)
.map(|hashout| hex::encode(hashout))
.map(hex::encode)
.map_err(|_| JwtError::OpenSSLError)?;

let skey = pkey::PKey::hmac(buf).map_err(|e| {
Expand Down
28 changes: 3 additions & 25 deletions src/crypto/mod.rs
Expand Up @@ -11,6 +11,7 @@ mod hs256;
mod rs256;
mod x509;

mod ms_oapxbc;
mod rsaes_oaep;

mod a128cbc_hs256;
Expand All @@ -32,7 +33,8 @@ pub use x509::{JwsX509Verifier, JwsX509VerifierBuilder};
pub use a128kw::JweA128KWEncipher;
pub use a256kw::JweA256KWEncipher;
pub use ecdhes_a128kw::{JweEcdhEsA128KWDecipher, JweEcdhEsA128KWEncipher};
pub use rsaes_oaep::JweRSAOAEPDecipher;
pub use ms_oapxbc::MsOapxbcSessionKey;
pub use rsaes_oaep::{JweRSAOAEPDecipher, JweRSAOAEPEncipher};

#[cfg(feature = "hsm-crypto")]
pub use tpm::JwsTpmSigner;
Expand Down Expand Up @@ -97,32 +99,8 @@ impl JweEnc {
.and_then(|jwe_decipher| jwe_decipher.decipher_inner(jwec)),
}
}

pub(crate) fn yield_cipher(self, key_buffer: &[u8]) -> Result<JweCipher, JwtError> {
match self {
JweEnc::A128GCM => {
a128gcm::JweA128GCMEncipher::try_from(key_buffer).map(JweCipher::A128GCM)
}
JweEnc::A256GCM => {
a256gcm::JweA256GCMEncipher::try_from(key_buffer).map(JweCipher::A256GCM)
}
JweEnc::A128CBC_HS256 => Err(JwtError::CipherUnavailable),
}
}
}

/// A [MS-OAPXBC] 3.2.5.1.2.2 yielded CEK. This is used as a form of key agreement
/// for MS clients, where this CEK can now be used to encipher and decipher arbitrary
/// content.
pub enum JweCipher {
/// AES-128-GCM CEK
A128GCM(a128gcm::JweA128GCMEncipher),
/// AES-256-GCM CEK
A256GCM(a256gcm::JweA256GCMEncipher),
}

// TODO: We need to support arbitrary message enc/dec here. Need to check what MS expects.

impl JweCompact {
#[cfg(test)]
fn check_vectors(
Expand Down